use std::collections::HashMap;
use std::path::PathBuf;
use anyhow::Result;
use eframe::{egui, CreationContext};
use std::time::{Duration, Instant};
use std::fs;

use crate::models::{ServerConfig, SpeedTestResult, View};
use crate::models::config::AppConfig;
use crate::ui::theme::{AppTheme, AppSizes};

pub mod state;
pub mod config;

/// 应用程序主结构体
pub struct App {
    // 应用状态
    pub connected: bool,
    pub current_server_idx: Option<usize>,
    pub servers: Vec<ServerConfig>,
    pub system_proxy_enabled: bool,
    pub speed_test_results: Vec<SpeedTestResult>,
    pub current_download_speed: f32,
    pub current_upload_speed: f32,
    pub current_view: View,
    pub import_url: String,
    
    // 配置
    pub app_config: AppConfig,
    pub config_path: PathBuf,
    
    // UI状态
    pub theme: AppTheme,
    pub sizes: AppSizes,
    pub server_dialog: crate::ui::server_dialog::ServerDialog,
    
    // 连接统计
    pub connection_time: u64,
    pub upload_usage: f64,
    pub download_usage: f64,
    pub last_update: Instant,
}

pub struct UISizes {
    pub nav_bar_width: f32,
    pub card_padding: f32,
}

impl Default for UISizes {
    fn default() -> Self {
        Self {
            nav_bar_width: 200.0,
            card_padding: 16.0,
        }
    }
}

impl Default for App {
    fn default() -> Self {
        Self {
            connected: false,
            current_server_idx: None,
            servers: Vec::new(),
            system_proxy_enabled: false,
            speed_test_results: Vec::new(),
            current_download_speed: 0.0,
            current_upload_speed: 0.0,
            current_view: View::default(),
            import_url: String::new(),
            app_config: AppConfig::new(),
            config_path: PathBuf::new(),
            theme: AppTheme::default(),
            sizes: AppSizes::default(),
            server_dialog: crate::ui::server_dialog::ServerDialog::default(),
            connection_time: 0,
            upload_usage: 0.0,
            download_usage: 0.0,
            last_update: Instant::now(),
        }
    }
}

impl App {
    /// 创建新的应用实例
    pub fn new(cc: &CreationContext) -> Self {
        // 设置自定义字体
        let mut fonts = egui::FontDefinitions::default();

        // 加载中文字体
        let font_path = "resources/HYSongYunLangHeiW-1.ttf";
        let font_data = std::fs::read(font_path).expect("无法加载字体文件");
        let font_name = "HYSongYunLangHeiW";
        
        // 添加字体
        fonts.font_data.insert(
            font_name.to_owned(),
            egui::FontData::from_owned(font_data),
        );

        // 设置中文字体为优先字体
        fonts
            .families
            .entry(egui::FontFamily::Proportional)
            .or_default()
            .insert(0, font_name.to_owned());

        // 将字体也添加到等宽字体系列中
        fonts
            .families
            .entry(egui::FontFamily::Monospace)
            .or_default()
            .push(font_name.to_owned());
        
        cc.egui_ctx.set_fonts(fonts);
        
        // 返回默认应用实例并添加样例数据
        let mut app = Self::default();
        
        // 加载或创建配置
        match app.load_config() {
            Ok(_) => {},
            Err(_) => {
                // 加载失败则设置默认设置
                app.app_config = AppConfig::new();
            }
        }
        
        // 设置初始主题
        let is_dark = app.app_config.dark_mode;
        let primary = app.app_config.primary_color;
        let secondary = app.app_config.secondary_color;
        
        app.theme = AppTheme::custom_theme(primary, secondary, is_dark);
        
        // 添加示例服务器
        app.add_example_servers();
        
        app
    }
    
    // 加载配置
    pub fn load_config(&mut self) -> Result<()> {
        // 确保配置目录存在
        if let Some(config_dir) = dirs::config_dir() {
            let app_config_dir = config_dir.join("banlsproxy");
            if !app_config_dir.exists() {
                std::fs::create_dir_all(&app_config_dir)?;
            }
            
            // 尝试加载配置
            let config_path = app_config_dir.join("config.json");
            if config_path.exists() {
                let config_content = std::fs::read_to_string(config_path)?;
                self.app_config = serde_json::from_str(&config_content)?;
            }
            
            // 尝试加载服务器列表
            let servers_path = app_config_dir.join("servers.json");
            if servers_path.exists() {
                let servers_content = std::fs::read_to_string(servers_path)?;
                self.servers = serde_json::from_str(&servers_content)?;
            }
            
            // 设置上次选择的服务器
            if let Some(idx) = self.app_config.last_server_index {
                if idx < self.servers.len() {
                    self.current_server_idx = Some(idx);
                }
            }
        }
        
        Ok(())
    }
    
    // 保存配置
    pub fn save_config(&self) -> Result<()> {
        if let Some(config_dir) = dirs::config_dir() {
            let app_config_dir = config_dir.join("banlsproxy");
            if !app_config_dir.exists() {
                std::fs::create_dir_all(&app_config_dir)?;
            }
            
            // 保存配置
            let config_path = app_config_dir.join("config.json");
            let config_json = serde_json::to_string_pretty(&self.app_config)?;
            std::fs::write(config_path, config_json)?;
            
            // 保存服务器列表
            let servers_path = app_config_dir.join("servers.json");
            let servers_json = serde_json::to_string_pretty(&self.servers)?;
            std::fs::write(servers_path, servers_json)?;
        }
        
        Ok(())
    }
    
    // 添加示例服务器
    pub fn add_example_servers(&mut self) {
        // 如果服务器列表为空，添加示例服务器
        if self.servers.is_empty() {
            self.servers.push(ServerConfig {
                name: "东京服务器".to_string(),
                host: "jp.example.com".to_string(),
                port: 443,
                server_type: crate::models::ServerType::Vmess,
                password: "uuid-example-1".to_string(),
                encryption: "aes-128-gcm".to_string(),
            });
            
            self.servers.push(ServerConfig {
                name: "美国服务器".to_string(),
                host: "us.example.com".to_string(),
                port: 443,
                server_type: crate::models::ServerType::Trojan,
                password: "uuid-example-2".to_string(),
                encryption: "chacha20-poly1305".to_string(),
            });
            
            // 设置默认选中的服务器
            if !self.servers.is_empty() {
                self.current_server_idx = Some(0);
            }
        }
    }
    
    // 切换连接状态
    pub fn toggle_connection(&mut self) {
        self.connected = !self.connected;
        
        if self.connected {
            // 重置连接时间计时器
            self.last_update = Instant::now();
            
            // 模拟随机初始流量为了显示效果
            use rand::Rng;
            let mut rng = rand::thread_rng();
            self.upload_usage = rng.gen_range(0.5..5.0);
            self.download_usage = rng.gen_range(1.0..10.0);
        } else {
            // 保存连接时间
            self.connection_time = 0;
        }
    }
    
    // 运行速度测试
    pub fn run_speed_test(&mut self, server_name: String) {
        // 模拟测速过程
        // 实际应用中需要真实的测速逻辑
        use rand::Rng;
        let mut rng = rand::thread_rng();
        
        // 生成随机延迟(0-300ms，或者模拟超时-1)
        let ping = if rng.gen_bool(0.9) {
            rng.gen_range(30.0..300.0)
        } else {
            -1.0 // 模拟超时
        };
        
        // 创建测速结果
        let result = SpeedTestResult {
            server_name,
            ping,
            timestamp: chrono::Local::now(),
        };
        
        // 添加或更新测速结果
        let existing_index = self.speed_test_results.iter().position(|r| r.server_name == result.server_name);
        if let Some(idx) = existing_index {
            self.speed_test_results[idx] = result;
        } else {
            self.speed_test_results.push(result);
        }
        
        // 按延迟排序结果，延迟低的排前面，超时的排后面
        self.speed_test_results.sort_by(|a, b| {
            if a.ping < 0.0 {
                std::cmp::Ordering::Greater
            } else if b.ping < 0.0 {
                std::cmp::Ordering::Less
            } else {
                a.ping.partial_cmp(&b.ping).unwrap_or(std::cmp::Ordering::Equal)
            }
        });
    }
} 